package com.ftwj.demo.modular.service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ftwj.demo.base.common.BaseService;
import com.ftwj.demo.base.util.PageInfoBean;
import com.ftwj.demo.modular.entity.FileBean;
import com.ftwj.demo.modular.vo.dao.FileVoDao;
import com.ftwj.demo.modular.vo.entity.FileVo;
import com.ftwj.demo.global.shiro.ShiroUtil;
import com.ftwj.demo.utils.file.FileHelper;
import com.ftwj.demo.utils.file.FileTypeUtil;
import com.ftwj.demo.utils.file.FileUpAndDownUtils;
import com.ftwj.demo.utils.file.FileUtils;
import com.ftwj.demo.utils.file.ZipCompressor;
import com.ftwj.demo.utils.image.ThumbnailGenerator;
import com.ftwj.demo.utils.key.TimestampID;
import com.ftwj.demo.utils.logs.LoggerUtil;

@Service
public class FileService extends BaseService<FileBean, String>{
	
	@Value("${file.uploadFolder}")
	private String uploadFolder;
	
	@Value("${file.staticAccessPath}")
	private String staticAccessPath;
	
	@Value("${file.temporaryPath}")
	private String temporaryPath;
	
	@Autowired
	private FileVoDao fileVoDao;

	/**
	 * <p>Title: upload</p>  
	 * <p>Description: 文件上传</p>  
	 * @param multipartFile 文件
	 * @param path 文件保存路径
	 * @param url 请求地址 
	 * @param description 文件描述
	 * @author HeYang
	 * @date 2020年4月17日  
	 * @version 1.0 
	 */
	@Transactional
	public String upload(MultipartFile multipartFile,String description,int returnType,String model) {
		FileBean file = new FileBean();
		String result = "";
		String fileId = "";
		String url = "";
		if(multipartFile != null) {
			fileId = TimestampID.getInstance().getRandomID();
			//文件名称
			String realFileName = multipartFile.getOriginalFilename();
			String suffix = FileUtils.getFileSuffix(realFileName);
			String fileName = fileId + "." +suffix;
			Integer type = FileTypeUtil.getType(suffix);
//			String fodder = FileTypeUtil.getFolder(type);
			String path = getDateCatalog(model);
			
			url = staticAccessPath.replace("**", path) + File.separator + fileName;
			path = uploadFolder + path;
			String filePath = path + File.separator + fileName;
			
			long fileSize = multipartFile.getSize();
			long range = 1024*50;
			
			if(fileSize < range) {
				FileUpAndDownUtils.uploadFile(multipartFile, filePath);// path = 目录路径+文件名
			}else {
				FileUpAndDownUtils.uploadFileBuffer(multipartFile, filePath);
			}
			String prefix = FileUtils.getFilePrefix(filePath);
			
			String thumbnailFilePath = "";
			if(type == 4) {
				try {
					thumbnailFilePath = path + prefix + "_thumbnail"+ "." +suffix;
					ThumbnailGenerator thumbnail = new ThumbnailGenerator();
					thumbnail.transform(filePath, thumbnailFilePath, 100, 100, 100);
				} catch (Exception e) {
					LoggerUtil.error("图片压缩失败");
				}
			}
			
			file.setFileId(fileId).setName(realFileName).setDescription(description).setThumb(thumbnailFilePath)
				.setPath(filePath).setUrl(url).setSize(fileSize).setType(type).setSuffix(suffix)
				.setCreateUser(ShiroUtil.getUserId()).setCreateTime(new Date());
			this.add(file);
		}
		result = (returnType == 1) ? fileId : url;
		return result;
	}

	/**
	 * <p>Description: 下载文件</p>  
	 * @param response
	 * @param id 
	 * @author HeYang
	 * @date 2020年4月17日  
	 * @version 1.0
	 */
	public void downlown(HttpServletRequest request,HttpServletResponse response,String id) {
		FileBean file = this.find(id);
		FileUpAndDownUtils.downloadFile(request,response, file.getPath(),file.getName());
		Integer down = Optional.ofNullable(file.getDownload()).orElse(0);
		file.setDownload(down+1).setFileId(id);
		this.save(file);
	}

	/**
	 * <p>Title: downloadZip</p>  
	 * <p>Description: 下载zip包</p>  
	 * @param response
	 * @param ids 
	 * @author HeYang
	 * @date 2020年4月17日  
	 * @version 1.0
	 */
	public void downloadZip(HttpServletRequest request,HttpServletResponse response, String ids) {
		List<File> list = new ArrayList<>();
		if(ids != null) {
			String[] fileIds = ids.split(",");
			for (String fileId : fileIds) {
				FileBean fileBean = this.find(fileId);
				File file = new File(fileBean.getPath());
				list.add(file);
			}
		}
		String random = TimestampID.getInstance().getRandomID();
		String fileName = "download_"+random+".zip";
		String path = temporaryPath + fileName;
		//1.压缩zip
		ZipCompressor.filesToZip(list, path);
		//2.发起zip文件下载
		FileUpAndDownUtils.downloadFile(request, response, path, fileName);
		//3.即时删除 
		FileHelper.deleteFile(path);
	}
	
	/**
	 * <p>Title: getDateCatalog</p>  
	 * <p>Description: 创建每日目录</p>  
	 * @author HeYang
	 * @date 2020年4月20日  
	 * @version 1.0
	 */
	private String getDateCatalog(String fodder) {
		SimpleDateFormat sdfY = new SimpleDateFormat("yyyy");
		SimpleDateFormat sdfMD = new SimpleDateFormat("MMdd");
		Date now = new Date();
		return fodder + File.separator + sdfY.format(now) + File.separator + sdfMD.format(now);
	}

	/**
	 * <p>Title: delete</p>  
	 * <p>Description: 物理删除，含文件物理删除</p>  
	 * @param id
	 * @return 
	 * @author HeYang
	 * @date 2020年4月20日  
	 * @version 1.0
	 */
	public int delete(String id) {
		FileBean file = this.find(id);
		int result =0;
		if(file != null) {
			boolean flag = FileHelper.deleteFile(file.getPath());
			int i = this.delById(id);
			if(flag && i > 0) {
				result = 1;
			}
		}
		return result;
	}

	/**
	 * <p>Title: page</p>  
	 * <p>Description: 分页查询文件列表</p>  
	 * @param pageInfo
	 * @param file
	 * @author HeYang
	 * @date 2020年4月20日  
	 * @version 1.0
	 */
	public PageInfoBean page(PageInfoBean pageInfo, FileBean file) {
		return this.pageMapByExample(file, pageInfo);
	}

	/**
	 * <p>Title: updateVo</p>  
	 * <p>Description: 修改fileVo</p>  
	 * @param fileVo
	 * @return 
	 * @author HeYang
	 * @date 2020年4月26日  
	 * @version 1.0
	 */
	public int updateVo(FileVo fileVo) {
		return fileVoDao.update(fileVo);
	}

}
